package com.example.caorl.job1.conc0302.lock;

import java.util.concurrent.locks.ReentrantLock;

public class TestFair {
    public static volatile int race = 0;
    public static ReentrantLock lock = new ReentrantLock(true); // 改成false会好100倍

    public static void increase() {
        lock.lock();
        race++;    //变量自增操作
        lock.unlock();
    }

    private static final int THREADS_COUNT = 20;

    public static void main(String[] args) throws InterruptedException {
        int count = Thread.activeCount();
        long now = System.currentTimeMillis();
        System.out.println(count);
//        AtomicReference<Thread> sign =new AtomicReference<>(); //与AtomicInteger类似，只不过这里是对对象的引用
        Thread[] threads = new Thread[THREADS_COUNT];  //定义20个线程
        for (int i = 0; i < THREADS_COUNT; i++) {
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 100000; i++) {
                        increase();
                    }
                }
            });
            threads[i].start();
        }//等待所有累加线程都结束
        while (Thread.activeCount() > count) {

            /* yield 使当前线程让出 CPU 时间片，线程从运行状态（Running）变为可执行状态（Runnable），处于可执行状态的线程有可能会再次获取到时间片继续执行，也有可能处于等待状态，直到再次获取到时间片。也就是说，后续会有两种情况：
             * 1、当前线程让出 CPU 时间片后，又立即获取到 CPU 时间片，进而继续执行当前方法。
             * 2、当前线程让出 CPU 时间片后，等待一段时间后获取到 CPU 时间片，进而继续执行当前方法。
             **/
            Thread.yield();
        }
        /*
        while (checkThreadRun(threads)){

        }
        */

        System.out.println(lock.getClass().getName() + " totalTimes  = " + (System.currentTimeMillis() - now));
        System.out.println("race result is:" + race);
    }

    /*private static boolean checkThreadRun(Thread[]threads) {
        boolean result = false;
        for (int i = 0;i<threads.length;i++){
            if (threads[i].isAlive()) {
                return true;
            }
        }
        return result;
    }*/
}

